package com.xjrsoft.module.app.controller;


import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.result.Response;
import com.xjrsoft.core.tool.node.ForestNodeMerger;
import com.xjrsoft.core.tool.utils.BeanUtil;
import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.StringPool;
import com.xjrsoft.module.app.dto.AppFunctionListDto;
import com.xjrsoft.module.app.dto.FunctionSubmitDto;
import com.xjrsoft.module.app.entity.XjrAppFunction;
import com.xjrsoft.module.app.entity.XjrAppFunctionButton;
import com.xjrsoft.module.app.entity.XjrAppFunctionColumn;
import com.xjrsoft.module.app.entity.XjrAppFunctionForm;
import com.xjrsoft.module.app.service.IXjrAppFunctionButtonService;
import com.xjrsoft.module.app.service.IXjrAppFunctionColumnService;
import com.xjrsoft.module.app.service.IXjrAppFunctionFormService;
import com.xjrsoft.module.app.service.IXjrAppFunctionService;
import com.xjrsoft.module.app.utils.FunctionUtil;
import com.xjrsoft.module.app.vo.*;
import com.xjrsoft.module.base.service.IXjrBaseDataItemService;
import com.xjrsoft.module.base.vo.DataItemDetailVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * APP端功能模块管理表 前端控制器
 * </p>
 *
 * @author jobob
 * @since 2021-02-23
 */
@RestController
@RequestMapping("/app-func")
@AllArgsConstructor
@Api(value = "/app-func",tags = "AppMyFunction")
public class XjrAppFunctionController {

    private final IXjrAppFunctionService appFunctionService;

    private final IXjrBaseDataItemService dataItemService;

    private final IXjrAppFunctionButtonService buttonService;

    private final IXjrAppFunctionColumnService columnService;

    private final IXjrAppFunctionFormService formService;

    @GetMapping("/{type}")
    @ApiOperation(value = "根据类型获取授权的移动功能菜单")
    public Response<List<AppFunctionVo>> getFunctionList(@PathVariable String type) {
        List<XjrAppFunction> appFunctionList = appFunctionService.getAuthFuncForCurUser(type);
        List<AppFunctionVo> appFunctionVoList = BeanUtil.copyList(appFunctionList, AppFunctionVo.class);
        return Response.ok(appFunctionVoList);
    }

    @GetMapping("/my")
    @ApiOperation(value = "获取当前登录人的授权")
    public Response<List<AppFunctionVo>> getAppModule(){
        return Response.ok(appFunctionService.getAppModuleForCurrentUser());
    }

    @GetMapping("/page")
    @ApiOperation(value = "获取所有App功能, 分页")
    public Response<PageOutput<AppFunctionVo>> getPageList(AppFunctionListDto listDto) {
        return Response.ok(appFunctionService.getPageList(listDto));
    }

    @GetMapping
    @ApiOperation(value = "获取所有授权的App功能")
    public Response<List<AppFunctionVo>> getList() {
        List<XjrAppFunction> list = appFunctionService.getAuthFuncForCurUser(null);
        return Response.ok(BeanUtil.copyList(list, AppFunctionVo.class));
    }

    @GetMapping("/other")
    @ApiOperation(value = "获取移动菜单下有权限的按钮、列表字段、表单字段编码")
    public Response<List<FunctionOtherVo>> getFunctionSubAuth() {
        List<FunctionOtherVo> list = appFunctionService.getFunctionSubAuth();
        return Response.ok(BeanUtil.copyList(list, FunctionOtherVo.class));
    }

    @GetMapping("/{id}/info")
    @ApiOperation(value = "编辑时获取移动菜单详情")
    public Response<FunctionInfoVo> info(@PathVariable String id) {
        FunctionInfoVo infoVo = new FunctionInfoVo();
        XjrAppFunction function = appFunctionService.getById(id);
        infoVo.setFunction(BeanUtil.copy(function, AppFunctionVo.class));

        List<XjrAppFunctionButton> buttonList = buttonService.getButtonByFunctionId(id);
        infoVo.setButtonVoList(BeanUtil.copyList(buttonList, FunctionButtonVo.class));

        List<XjrAppFunctionColumn> columnList = columnService.getColumnByFunctionId(id);
        infoVo.setColumnVoList(BeanUtil.copyList(columnList, FunctionColumnVo.class));

        List<XjrAppFunctionForm> formList = formService.getFormByFunctionId(id);
        List<FunctionFormVo> formTreeVoList = BeanUtil.copyList(formList, FunctionFormVo.class);
        infoVo.setFormVoList(ForestNodeMerger.merge(formTreeVoList));

        return Response.ok(infoVo);
    }

    @GetMapping("/category-tree")
    @ApiOperation(value = "获取所有授权的App功能")
    public Response<Map<String, List<Object>>> getCategoryTreeList() {
        Map<String, List<Object>> resultMap = new HashMap<>();
        List<XjrAppFunction> appFunctionList = appFunctionService.getAuthFuncForCurUser(null);
        if (CollectionUtil.isNotEmpty(appFunctionList)) {
            List<AppFunctionTreeVo> appFunctionVoList = BeanUtil.copyList(appFunctionList, AppFunctionTreeVo.class);
            List<String> functionIdList = appFunctionVoList.stream().map(function -> function.getId()).collect(Collectors.toList());
            List<DataItemDetailVo> dataItemDetailVoList = dataItemService.getDataItemDetails("function");

            //按钮
            List<XjrAppFunctionButton> buttonList = buttonService.getAuthButtonForCurUser(functionIdList);
            List<AppFunctionTreeVo> buttonFunctionTreeVo = FunctionUtil.buildSubFunctionTree(appFunctionVoList, buttonList, FunctionButtonTreeVo.class);
            resultMap.put("buttonList", FunctionUtil.buildCategoryTree(dataItemDetailVoList, buttonFunctionTreeVo));

            //列表字段
            List<XjrAppFunctionColumn> columnList = columnService.getAuthColumnForCurUser(functionIdList);
            List<AppFunctionTreeVo> columnFunctionTreeVo = FunctionUtil.buildSubFunctionTree(appFunctionVoList, columnList, FunctionColumnTreeVo.class);
            resultMap.put("columnList", FunctionUtil.buildCategoryTree(dataItemDetailVoList, columnFunctionTreeVo));

            //表单
            List<XjrAppFunctionForm> formList = formService.getAuthFormForCurUser(functionIdList);
            List<AppFunctionTreeVo> formFunctionTreeVo = FunctionUtil.buildSubFunctionTree(appFunctionVoList, formList, FunctionFormTreeVo.class);
            resultMap.put("formList", FunctionUtil.buildCategoryTree(dataItemDetailVoList, formFunctionTreeVo));
    
            //菜单
            resultMap.put("functionList", FunctionUtil.buildCategoryTree(dataItemDetailVoList, appFunctionVoList));
        }
        return Response.ok(resultMap);
    }

    @PostMapping
    @ApiOperation(value = "新增App功能")
    public Response addAppFunction(@RequestBody FunctionSubmitDto dto) {
        XjrAppFunction appFunction = BeanUtil.copy(dto.getFunctionDto(), XjrAppFunction.class);
        List<XjrAppFunctionButton> buttonList = BeanUtil.copyList(dto.getButtonDtoList(), XjrAppFunctionButton.class);
        List<XjrAppFunctionColumn> columnList = BeanUtil.copyList(dto.getColumnDtoList(), XjrAppFunctionColumn.class);
        List<XjrAppFunctionForm> formList = BeanUtil.copyList(dto.getFormDtoList(), XjrAppFunctionForm.class);
        return Response.ok(appFunctionService.saveAppFunction(appFunction, buttonList, columnList, formList));
    }

    @PutMapping("/{id}")
    @ApiOperation(value = "修改App功能")
    public Response updateAppFunction(@PathVariable String id, @RequestBody FunctionSubmitDto dto) {
        XjrAppFunction appFunction = BeanUtil.copy(dto.getFunctionDto(), XjrAppFunction.class);
        List<XjrAppFunctionButton> buttonList = BeanUtil.copyList(dto.getButtonDtoList(), XjrAppFunctionButton.class);
        List<XjrAppFunctionColumn> columnList = BeanUtil.copyList(dto.getColumnDtoList(), XjrAppFunctionColumn.class);
        List<XjrAppFunctionForm> formList = BeanUtil.copyList(dto.getFormDtoList(), XjrAppFunctionForm.class);
        return Response.ok(appFunctionService.updateAppFunction(id, appFunction, buttonList, columnList, formList));
    }

    @DeleteMapping("/{ids}")
    @ApiOperation(value = "删除App功能")
    public Response deleteAppFunction(@PathVariable String ids) {
        String[] idArray = StringUtils.split(ids, StringPool.COMMA);
        if (idArray.length > 1) {
            return Response.ok(appFunctionService.removeByIds(Arrays.asList(idArray)));
        } else {
            return Response.ok(appFunctionService.removeById(idArray[0]));
        }

    }

}
